package com.skp.shaphan.ui;

import java.awt.Component;
import java.awt.Point;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import com.skp.shaphan.SQLEditorsPane;

/**
 * This is a special glass pane that intercepts events and allows you
 * to preview the events
 * @author Stephen Phillips
 *
 */
public class CustomGlassPane extends JComponent {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 2031818935362712345L;

	/*
	 * This is the item to cover up and intercept
	 * events
	 */
	private SQLEditorsPane editorsPane;

	public CustomGlassPane(SQLEditorsPane editorsPane) {
		this.editorsPane = editorsPane;
		
		ComponentAdapter shapeChangeListener = new ComponentAdapter() {
			@Override
			public void componentMoved(ComponentEvent e) {
				updateSize();
			}
			@Override
			public void componentResized(ComponentEvent e) {
				updateSize();
			}
			@Override
			public void componentShown(ComponentEvent e) {
				updateSize();
			}
		};
		editorsPane.addComponentListener(shapeChangeListener);
		addMouseMotionListener(mouseMotionListener);
		addMouseListener(mouseListener);
		
		updateSize();
	}
	
	private MouseMotionListener mouseMotionListener = new MouseMotionListener() {
		@Override
		public void mouseMoved(MouseEvent me) {
			JPanel uiView = editorsPane.getUIView();
			Point sourcePoint = me.getPoint();
			Component src = (Component)me.getSource();
			src = CustomGlassPane.this;
			Point destPoint = SwingUtilities.convertPoint(src, sourcePoint, uiView);
			Component target = SwingUtilities.getDeepestComponentAt(uiView, destPoint.x, destPoint.y);
			SQLEditor currentEditor = null;
			if(target != null) {
				if(target instanceof SQLEditor) {
					// we are good to go
					currentEditor = (SQLEditor) target;
				} else {
					Component parent = target.getParent();
					while(parent != null) {
						if(parent instanceof SQLEditor) {
							currentEditor = (SQLEditor) parent;
							parent = null;
						} else {
							parent = parent.getParent();
						}
					}
				}
			}
			editorsPane.setMousedEditor(currentEditor);
			
			// redispatch the event so the controls underneath still work
			if(target != null) {
				Point targetPoint = SwingUtilities.convertPoint(uiView, destPoint, target);
				target.dispatchEvent(new MouseEvent(target, me.getID(), me.getWhen(), me.getModifiers(), targetPoint.x, targetPoint.y, me.getClickCount(), me.isPopupTrigger()));
			}
		}
		
		@Override
		public void mouseDragged(MouseEvent me) {
			JPanel uiView = editorsPane.getUIView();
			Point sourcePoint = me.getPoint();
			Component src = (Component)me.getSource();
			src = CustomGlassPane.this;
			Point destPoint = SwingUtilities.convertPoint(src, sourcePoint, uiView);
			Component target = SwingUtilities.getDeepestComponentAt(uiView, destPoint.x, destPoint.y);
			
			// redispatch the event so the controls underneath still work
			if(target != null) {
				Point targetPoint = SwingUtilities.convertPoint(uiView, destPoint, target);
				target.dispatchEvent(new MouseEvent(target, me.getID(), me.getWhen(), me.getModifiers(), targetPoint.x, targetPoint.y, me.getClickCount(), me.isPopupTrigger()));
			}
		}
	};
	
	private MouseListener mouseListener = new MouseListener() {

		@Override
		public void mouseClicked(MouseEvent me) {
			JPanel uiView = editorsPane.getUIView();
			Point sourcePoint = me.getPoint();
			Component src = (Component)me.getSource();
			src = CustomGlassPane.this;
			Point destPoint = SwingUtilities.convertPoint(src, sourcePoint, uiView);
			Component target = SwingUtilities.getDeepestComponentAt(uiView, destPoint.x, destPoint.y);
			
			// redispatch the event so the controls underneath still work
			if(target != null) {
				Point targetPoint = SwingUtilities.convertPoint(uiView, destPoint, target);
				target.dispatchEvent(new MouseEvent(target, me.getID(), me.getWhen(), me.getModifiers(), targetPoint.x, targetPoint.y, me.getClickCount(), me.isPopupTrigger()));
			}
		}

		@Override
		public void mouseEntered(MouseEvent me) {
			JPanel uiView = editorsPane.getUIView();
			Point sourcePoint = me.getPoint();
			Component src = (Component)me.getSource();
			src = CustomGlassPane.this;
			Point destPoint = SwingUtilities.convertPoint(src, sourcePoint, uiView);
			Component target = SwingUtilities.getDeepestComponentAt(uiView, destPoint.x, destPoint.y);
			
			// redispatch the event so the controls underneath still work
			if(target != null) {
				Point targetPoint = SwingUtilities.convertPoint(uiView, destPoint, target);
				target.dispatchEvent(new MouseEvent(target, me.getID(), me.getWhen(), me.getModifiers(), targetPoint.x, targetPoint.y, me.getClickCount(), me.isPopupTrigger()));
			}
		}

		@Override
		public void mouseExited(MouseEvent me) {
			JPanel uiView = editorsPane.getUIView();
			Point sourcePoint = me.getPoint();
			Component src = (Component)me.getSource();
			src = CustomGlassPane.this;
			Point destPoint = SwingUtilities.convertPoint(src, sourcePoint, uiView);
			Component target = SwingUtilities.getDeepestComponentAt(uiView, destPoint.x, destPoint.y);
			
			// redispatch the event so the controls underneath still work
			if(target != null) {
				Point targetPoint = SwingUtilities.convertPoint(uiView, destPoint, target);
				target.dispatchEvent(new MouseEvent(target, me.getID(), me.getWhen(), me.getModifiers(), targetPoint.x, targetPoint.y, me.getClickCount(), me.isPopupTrigger()));
			}
		}

		@Override
		public void mousePressed(MouseEvent me) {
			JPanel uiView = editorsPane.getUIView();
			Point sourcePoint = me.getPoint();
			Component src = (Component)me.getSource();
			src = CustomGlassPane.this;
			Point destPoint = SwingUtilities.convertPoint(src, sourcePoint, uiView);
			Component target = SwingUtilities.getDeepestComponentAt(uiView, destPoint.x, destPoint.y);
			
			// redispatch the event so the controls underneath still work
			if(target != null) {
				Point targetPoint = SwingUtilities.convertPoint(uiView, destPoint, target);
				target.dispatchEvent(new MouseEvent(target, me.getID(), me.getWhen(), me.getModifiers(), targetPoint.x, targetPoint.y, me.getClickCount(), me.isPopupTrigger()));
			}
		}

		@Override
		public void mouseReleased(MouseEvent me) {
			JPanel uiView = editorsPane.getUIView();
			Point sourcePoint = me.getPoint();
			Component src = (Component)me.getSource();
			src = CustomGlassPane.this;
			Point destPoint = SwingUtilities.convertPoint(src, sourcePoint, uiView);
			Component target = SwingUtilities.getDeepestComponentAt(uiView, destPoint.x, destPoint.y);
			
			// redispatch the event so the controls underneath still work
			if(target != null) {
				Point targetPoint = SwingUtilities.convertPoint(uiView, destPoint, target);
				target.dispatchEvent(new MouseEvent(target, me.getID(), me.getWhen(), me.getModifiers(), targetPoint.x, targetPoint.y, me.getClickCount(), me.isPopupTrigger()));
			}
		}
		
	};
	
	@Override
	public void setVisible(boolean visible) {
		if(visible) {
			updateSize();
		}
		super.setVisible(visible);
	}
	
	public void updateSize() {
		setBounds(editorsPane.getBounds());
	}	
}
